import {
  Button,
  Flex,
  Form,
  message,
  Modal,
  Select,
  SelectProps,
  Steps,
  Input,
  Checkbox,
  Space,
} from "antd";
import { useEffect, useState } from "react";
import { ListConnections } from "../../wailsjs/go/services/ConnectionService";
import { types } from "../../wailsjs/go/models";
import {
  ListDatabases,
  ListTables,
} from "../../wailsjs/go/services/MysqlService";

const ConnectionConfigSelect = (props: Omit<SelectProps, "options">) => {
  const [connections, setConnections] = useState<types.Connection[]>([]);
  useEffect(() => {
    ListConnections().then((res) => {
      setConnections(res.data);
    });
  }, []);
  return (
    <Select
      {...props}
      options={connections.map((item) => ({
        label: item.name,
        value: item.uuid,
      }))}
    />
  );
};

const DatabaseSelect = ({
  connectionUuid,
  value,
  onChange,
  ...props
}: Omit<SelectProps, "options"> & { connectionUuid: string }) => {
  const [databases, setDatabases] = useState<string[]>([]);
  useEffect(() => {
    ListDatabases(connectionUuid).then((res) => {
      if (res.success) {
        setDatabases(res.data);
      } else {
        message.error(res.msg);
      }
    });
  }, [connectionUuid]);
  useEffect(() => {
    if (!value) {
      return;
    }
    if (!databases.includes(value)) {
      onChange?.(undefined);
    }
  }, [databases, value, onChange]);
  return (
    <Select
      {...props}
      options={databases.map((item) => ({ label: item, value: item }))}
      value={value}
      onChange={onChange}
    />
  );
};

const TableSelect = ({
  connectionUuid,
  database,
  value,
  onChange,
  ...props
}: Omit<SelectProps, "options"> & {
  connectionUuid: string;
  database: string;
}) => {
  const [tables, setTables] = useState<string[]>([]);
  useEffect(() => {
    if (connectionUuid && database) {
      ListTables(connectionUuid, database).then((res) => {
        if (res.success) {
          setTables(res.data);
        } else {
          message.error(res.msg);
        }
      });
    }
  }, [connectionUuid, database]);
  useEffect(() => {
    if (!value) {
      return;
    }
    if (!tables.includes(value)) {
      onChange?.(undefined);
    }
  }, [tables, value, onChange]);
  return (
    <Select
      {...props}
      options={tables.map((item) => ({ label: item, value: item }))}
      value={value}
      onChange={onChange}
    />
  );
};

const DataTransmission = () => {
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [form] = Form.useForm();
  const [currentStep, setCurrentStep] = useState(0);
  const [tables, setTables] = useState<string[]>([]);
  const [searchText, setSearchText] = useState("");

  const sourceConnectionUuid = Form.useWatch(["source", "connection"], form);
  const targetConnectionUuid = Form.useWatch(["target", "connection"], form);
  const sourceDatabase = Form.useWatch(["source", "database"], form);
  const targetDatabase = Form.useWatch(["target", "database"], form);
  const selectedTables = Form.useWatch("tables", form) || [];

  const isAllSelected =
    sourceConnectionUuid &&
    targetConnectionUuid &&
    sourceDatabase &&
    targetDatabase;
  const isSameDatabase =
    isAllSelected &&
    sourceConnectionUuid === targetConnectionUuid &&
    sourceDatabase === targetDatabase;

  useEffect(() => {
    if (currentStep === 1 && sourceConnectionUuid && sourceDatabase) {
      ListTables(sourceConnectionUuid, sourceDatabase).then((res) => {
        if (res.success) {
          setTables(res.data);
        } else {
          message.error(res.msg);
        }
      });
    }
  }, [currentStep, sourceConnectionUuid, sourceDatabase]);

  useEffect(() => {
    if (isAllSelected && isSameDatabase) {
      message.error("源数据库和目标数据库不能相同");
    }
  }, [isAllSelected, isSameDatabase]);

  const handleNext = () => {
    if (currentStep === 0) {
      form.validateFields().then(() => {
        if (!isSameDatabase) {
          setCurrentStep(1);
        }
      });
    }
  };

  const handlePrev = () => {
    setCurrentStep(0);
  };

  const filteredTables = tables.filter((table) =>
    table.toLowerCase().includes(searchText.toLowerCase())
  );

  return (
    <>
      <Button onClick={() => setIsModalOpen(true)}>数据传输</Button>
      <Modal
        open={isModalOpen}
        onCancel={() => {
          setIsModalOpen(false);
          setCurrentStep(0);
          form.resetFields();
          setSearchText("");
        }}
        closable={false}
        footer={null}
        width={800}
        style={{ top: 20 }}
        destroyOnClose={true}
        bodyStyle={{
          maxHeight: "calc(100vh - 200px)",
          display: "flex",
          flexDirection: "column",
        }}
      >
        <Steps
          current={currentStep}
          items={[
            {
              title: "选择数据库",
            },
            {
              title: "选择表",
            },
          ]}
          style={{ marginBottom: 24 }}
        />
        <Form form={form} layout="vertical" style={{ flex: 1 }}>
          {currentStep === 0 ? (
            <Flex gap={16}>
              <div style={{ flex: 1 }}>
                <Form.Item
                  label="源连接"
                  name={["source", "connection"]}
                  rules={[{ required: true, message: "请选择源连接" }]}
                >
                  <ConnectionConfigSelect />
                </Form.Item>
                <Form.Item
                  label="源数据库"
                  name={["source", "database"]}
                  rules={[{ required: true, message: "请选择源数据库" }]}
                >
                  <DatabaseSelect connectionUuid={sourceConnectionUuid} />
                </Form.Item>
              </div>
              <div style={{ flex: 1 }}>
                <Form.Item
                  label="目标连接"
                  name={["target", "connection"]}
                  rules={[{ required: true, message: "请选择目标连接" }]}
                >
                  <ConnectionConfigSelect />
                </Form.Item>
                <Form.Item
                  label="目标数据库"
                  name={["target", "database"]}
                  rules={[{ required: true, message: "请选择目标数据库" }]}
                >
                  <DatabaseSelect connectionUuid={targetConnectionUuid} />
                </Form.Item>
              </div>
            </Flex>
          ) : (
            <div style={{ display: "flex", flexDirection: "column", flex: 1 }}>
              <Input.Search
                placeholder="搜索表名"
                allowClear
                value={searchText}
                onChange={(e) => setSearchText(e.target.value)}
                style={{ marginBottom: 16 }}
              />
              <div
                style={{
                  overflowY: "auto",
                  maxHeight: "calc(100vh - 400px)",
                  padding: "8px 0",
                }}
              >
                <Form.Item
                  name="tables"
                  rules={[{ required: true, message: "请选择至少一个表" }]}
                >
                  <Checkbox.Group style={{ width: "100%" }}>
                    <Space direction="vertical" style={{ width: "100%" }}>
                      {filteredTables.map((table) => (
                        <Checkbox key={table} value={table}>
                          {table}
                        </Checkbox>
                      ))}
                    </Space>
                  </Checkbox.Group>
                </Form.Item>
              </div>
            </div>
          )}
          <Flex
            justify="space-between"
            style={{
              marginTop: 16,
              paddingTop: 16,
              borderTop: "1px solid #f0f0f0",
            }}
          >
            {currentStep === 1 && <Button onClick={handlePrev}>上一步</Button>}
            <Button
              type="primary"
              onClick={currentStep === 0 ? handleNext : undefined}
              disabled={
                currentStep === 0
                  ? !isAllSelected || isSameDatabase
                  : selectedTables.length === 0
              }
            >
              {currentStep === 0 ? "下一步" : "开始传输"}
            </Button>
          </Flex>
        </Form>
      </Modal>
    </>
  );
};

export default DataTransmission;
